<h2>Why is this an issue?</h2>
<p>When working with LINQ in C#, it is recommended to pay attention to the order in which methods are chained, especially when using
<code>Where</code> and <code>OrderBy</code> methods. It is advised to call the <code>Where</code> method before <code>OrderBy</code> because
<code>Where</code> filters the elements of the sequence based on a given condition and returns a new sequence containing only the elements that
satisfy that condition. Calling <code>OrderBy</code> before <code>Where</code>, may end up sorting elements that will be later discarded, which can
lead to inefficiency. Conversely, calling <code>Where</code> before <code>OrderBy</code>, will first filter the sequence to include only the elements
of interest, and then sort them based on the specified order.</p>
<h3>What is the potential impact?</h3>
<p>We measured at least 2x improvement in execution time. For more details see the <code>Benchmarks</code> section from the <code>More info</code>
tab.</p>
<h2>How to fix it</h2>
<p>The issue can be fixed by calling <code>Where</code> before <code>OrderBy</code>.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
Public Function GetSortedFilteredList(data As IEnumerable(Of Integer)) As IEnumerable(Of Integer)
    Return data.OrderBy(Function(x) x).Where(Function(x) x Mod 2 = 0)
End Function
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
Public Function GetSortedFilteredList(data As IEnumerable(Of Integer)) As IEnumerable(Of Integer)
    Return data.Where(Function(x) x Mod 2 = 0).OrderBy(Function(x) x)
End Function
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.orderby">Enumerable.OrderBy</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where">Enumerable.Where</a> </li>
</ul>
<h3>Articles &amp; blog posts</h3>
<ul>
  <li> <a href="https://stackoverflow.com/questions/7499384/does-the-order-of-linq-functions-matter/7499454#7499454">Jon Skeet’s explanation on Stack
  Overflow</a> </li>
</ul>
<h3>Benchmarks</h3>
<table>
  <colgroup>
    <col style="width: 25%;">
    <col style="width: 25%;">
    <col style="width: 25%;">
    <col style="width: 25%;">
  </colgroup>
  <thead>
    <tr>
      <th>Method</th>
      <th>Runtime</th>
      <th>Mean</th>
      <th>Standard Deviation</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><p>OrderByThenWhere</p></td>
      <td><p>.NET 7.0</p></td>
      <td><p>175.36 ms</p></td>
      <td><p>5.101 ms</p></td>
    </tr>
    <tr>
      <td><p>WhereThenOrderBy</p></td>
      <td><p>.NET 7.0</p></td>
      <td><p>85.58 ms</p></td>
      <td><p>1.697 ms</p></td>
    </tr>
  </tbody>
</table>
<h4>Glossary</h4>
<ul>
  <li> <a href="https://en.wikipedia.org/wiki/Arithmetic_mean">Mean</a> </li>
  <li> <a href="https://en.wikipedia.org/wiki/Standard_deviation">Standard Deviation</a> </li>
</ul>
<p>The results were generated by running the following snippet with <a href="https://github.com/dotnet/BenchmarkDotNet">BenchmarkDotNet</a>:</p>
<pre>
private IList&lt;int&gt; data;
private static readonly Random Random = new Random();

[Params(1_000_000)]
public int NumberOfEntries;

[GlobalSetup]
public void Setup() =&gt;
    data = Enumerable.Range(0, NumberOfEntries).Select(x =&gt; Random.Next(0, NumberOfEntries)).ToList();

[Benchmark(Baseline = true)]
public void OrderByThenWhere() =&gt;
    _ = data.OrderBy(x =&gt; x).Where(x =&gt; x % 2 == 0 ).ToList();  // OrderBy followed by Where

[Benchmark]
public void WhereThenOrderBy() =&gt;
    _ = data.Where(x =&gt; x % 2 == 0 ).OrderBy(x =&gt; x).ToList();  // Where followed by OrderBy
</pre>
<p>Hardware configuration:</p>
<pre>
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores
.NET SDK=7.0.203
  [Host]               : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .NET 7.0             : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
</pre>

